package lew.bing.exp.commons;

import org.springframework.beans.BeanUtils;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by 刘国兵 on 2018/8/6.
 */
public class JavaBeanToMap {

    @SuppressWarnings("unchecked")
    public static <T>Map beanToMap(T bean, Class<T> clazz) {
        try {
            BeanInfo beaninfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] propertyDescriptors = beaninfo.getPropertyDescriptors();
            Map map = new HashMap();
            if (propertyDescriptors != null) {
                for (PropertyDescriptor descriptor: propertyDescriptors) {
                    Method readMethod = descriptor.getReadMethod();
                    if (readMethod != null && readMethod.getParameterCount() == 0 && !descriptor.getName().equals("class")) {
                        map.put(descriptor.getName(), readMethod.invoke(bean));
                    }
                }
            }
            return map;
        } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
            return null;
        }
    }

    /**
     * 必须有默认的构造方法
     * @param properties
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T>T mapToBean(Map properties, Class<T> clazz) {
        try {
            BeanInfo beaninfo = Introspector.getBeanInfo(clazz);
            T t = clazz.newInstance();
            PropertyDescriptor[] propertyDescriptors = beaninfo.getPropertyDescriptors();
            if (propertyDescriptors != null) {
                for (PropertyDescriptor desc:
                     propertyDescriptors) {
                    String name = desc.getName();
                    if (properties.containsKey(name)) {
                        Method writeMethod = desc.getWriteMethod();
                        if (writeMethod != null) {
                            try {
                                writeMethod.invoke(t, properties.get(name));

                            }catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
            return t;
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) {
        Abc abc = new Abc(1,"2");
        System.out.println(beanToMap(abc, Abc.class));
        Map map = new HashMap();
        map.put("a",2);
        map.put("b","abc");
        System.out.println(mapToBean(map, Abc.class));
    }

}
